package com.chao.base.io.socketio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

/**
 * @author : Rookie
 * @description :
 * @date : 2023/10/19
 */
public class NioSelectorDemo {

    public static void main(String[] args) {
        try {
            int port = 9527;
            // 服务端socket
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.socket().bind(new InetSocketAddress(port));
            // 设置为非阻塞的方式
            serverChannel.configureBlocking(false);
            // 创建selector 注册channel
            Selector selector = Selector.open();
            // 设置selector对客户端连接感兴趣
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务端启动，监听" + port + "端口");

            while (true) {
                // 阻塞 等待需要处理的事件发生
                selector.select();
                // 获取selector中注册的全部事件
                Set<SelectionKey> selectionKeys = selector.keys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();

                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    // 如果是连接事件
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel serverSocket = (ServerSocketChannel) selectionKey.channel();
                        SocketChannel clientChannel = serverSocket.accept();
                        clientChannel.configureBlocking(false);
                        // 注册读事件 读取客户端发送的数据 如果要给客户端发数据 也可以注册写事件
                        clientChannel.register(selector, SelectionKey.OP_READ);
                        System.out.println("客户端连接成功");
                    } else if (selectionKey.isReadable()) {
                        // 读事件  发生读事件的客户端
                        SocketChannel clientChannel = (SocketChannel) selectionKey.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(6);
                        int len = clientChannel.read(buffer);
                        if (len > 0) {
                            System.out.println("接收到客户端的消息："+new String(buffer.array(), 0, len));
                        } else if (len == -1) {
                            System.out.println("客户端断开连接");
                            clientChannel.close();
                        }
                    }
                    iterator.remove();
                }
//                // 接受客户端连接
//                SocketChannel clientChannel = serverChannel.accept();
//                if (clientChannel != null) {
//                    System.out.println("接收到客户端连接：" + clientChannel.getRemoteAddress());
//
//                    // 读取客户端连接的数据
//                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
//                    int byteRead = clientChannel.read(byteBuffer);
//                    if (byteRead > 0) {
//                        byteBuffer.flip();
//                        byte[] bytes = new byte[byteBuffer.remaining()];
//                        byteBuffer.get(bytes);
//                        String s = new String(bytes, StandardCharsets.UTF_8);
//                        System.out.println("收到客户端发送的消息，内容是：" + s);
//                    }
//                }

//                if (clientChannel != null) {
//                    clientChannel.close();
//                    System.out.println("关闭客户端连接" + clientChannel.getRemoteAddress());
//                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
